﻿using System;
using System.Collections.Generic;
using System.Linq;
using Crap4Net.CoverageParsers;
using Crap4Net.CCParsers;

namespace Crap4Net
{


    public class CrapAnalyzer
    {

        public static ICCParser CCParser { get; set; }

        public static ICoverageParser CoverageParser { get; set; }

        public static IList<CombinedDataEntry> CreateCrapReport(string coverageReport, string ccmReport)
        {
            //System.Diagnostics.Debugger.Break();
            LoadData(coverageReport, ccmReport);

            var results = new List<CombinedDataEntry>();
            var combinedData = Join(CoverageParser.Data, CCParser.Data);

            foreach (var item in combinedData)
            {
                var crapValue = CrapCalculator.CalculateCrap(item.CyclomaticComplexity, item.CoverageData);
                item.Crap = crapValue;

                results.Add(item);
            }
            return results;
        }

        private static void LoadData(string coverageReport, string ccmReport)
        {
            if (null == CCParser)
            {
                throw new ApplicationException("CC Parser object not specified. Cant parse CC data without a parser.");
            }
            if (null == CoverageParser)
            {
                throw new ApplicationException("Coverage Parser object not specified. Cant parse Coverage data without a parser.");

            }
            CCParser.LoadData(ccmReport);
            CoverageParser.LoadData(coverageReport);
        }

        private static CoverageDataEntry LocateCovCData(MethodSignature method, IList<CoverageDataEntry> ccData)
        {
            var answer = (from data in ccData
                          where (MethodMatcher.IsMatching(data.Method,method)==true)
                          select data);
            return answer.SingleOrDefault();
        }

        private static IList<CombinedDataEntry> Join(IList<CoverageDataEntry> coverageData, IList<CCDataEntry> ccData)
        {
            var results = new List<CombinedDataEntry>();
            foreach (var item in ccData)
            {
                var covEntry = LocateCovCData(item.Method, coverageData);
                CombinedDataEntry CombinedData;
                if (covEntry==null)
                    CombinedData = new CombinedDataEntry(item.Method, 0, item.CyclomaticComplexity);
                else
                    CombinedData = new CombinedDataEntry(item.Method, covEntry.CoverageData, item.CyclomaticComplexity);
                
                results.Add(CombinedData);
                //else
                //{
                //    Console.WriteLine("Didnt Find MEthod: {0}.{1}", item.Method.TypeName, item.Method.MethodName);
                //}
            }
            return results;
        }

        
    }
}
